package com.tank.net;

import com.tank.net.msg.Msg;
import com.tank.net.msg.MsgTypeEnum;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * @author CaoBaoYin
 * @since 21/11/1 17:38
 */
public class TankMsgDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 消息体类型 + 字节长度 = 4 + 4
        if (in.readableBytes() < 8) return; // 解决tcp的拆包和粘包 例如有“abc”三个字符，可能是“a”一个包或“bc”一个包。服务端有可能收到两个包，或三个包都有可能。

        in.markReaderIndex(); // 标记读取角标位置

        MsgTypeEnum msgType = MsgTypeEnum.values()[in.readInt()];
        int msgLength = in.readInt();

        // 判断数据长度是否够
        if (in.readableBytes() < msgLength) {
            in.resetReaderIndex();
            return;
        }

        Msg msg = (Msg) Class.forName("com.tank.net.msg.".concat(msgType.hump()).concat("Msg")).newInstance();

        byte[] bytes = new byte[msgLength];
        in.readBytes(bytes);
        msg.parse(bytes);

        out.add(msg);

        // System.out.println("解码消息：" + msg);
    }
}
